//
//  ExcelCell.swift
//  SearchHeader
//
//  Created by 万孟超 on 2023/10/13.
//

import Cocoa
import SnapKit

class ExcelView: NSTableView {
    
    var model: SearchResult
    
    init(model: SearchResult) {
        self.model = model
        super.init(frame: .zero)
        delegate = self
        dataSource = self
        headerView = nil
        usesAutomaticRowHeights = true
        backgroundColor = .clear
        let column = NSTableColumn()
        addTableColumn(column)
        reloadData()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    
    func createStackCell() -> NSView {
        
        let stackView = NSStackView()
        stackView.orientation = .horizontal
        stackView.distribution = .fill
        stackView.spacing = 0
        let frameworkCell = Excel(titleText: "Framerowk")
        frameworkCell.snp.makeConstraints { make in
            make.size.equalTo(NSMakeSize(130, 40))
        }
        let filekCell = Excel(titleText: "不规范头文件")
        filekCell.snp.makeConstraints { make in
            make.size.equalTo(NSMakeSize(200, 40))
        }
        let inFileCell = Excel(titleText: "所在的文件")
        inFileCell.snp.makeConstraints { make in
            make.size.equalTo(NSMakeSize(300, 40))
        }
        let lineInFileCell = Excel(titleText: "行")
        lineInFileCell.snp.makeConstraints { make in
            make.size.equalTo(NSMakeSize(40, 40))
        }
        let errorCell = Excel(titleText: "错误的格式")
        errorCell.snp.makeConstraints { make in
            make.size.equalTo(NSMakeSize(350, 40))
        }
        let rightCell = Excel(titleText: "正确的格式")
        rightCell.snp.makeConstraints { make in
            make.size.equalTo(NSMakeSize(400, 40))
        }
        let replaceCell = ExcelButton(title: "全局替换")
        replaceCell.viewTag = -2
        replaceCell.snp.makeConstraints { make in
            make.size.equalTo(NSMakeSize(100, 40))
        }
        stackView.addArrangedSubview(frameworkCell)
        stackView.addArrangedSubview(filekCell)
        stackView.addArrangedSubview(inFileCell)
        stackView.addArrangedSubview(lineInFileCell)
        stackView.addArrangedSubview(errorCell)
        stackView.addArrangedSubview(rightCell)
        stackView.addArrangedSubview(replaceCell)
        return stackView
    }
}

extension ExcelView: NSTableViewDelegate, NSTableViewDataSource {
    func numberOfRows(in tableView: NSTableView) -> Int {
        model.results.count + 1
    }
    
    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
        if row != 0 {
            let errorFRV = ExcelFRV(model: model.results[row - 1], tag: row)
            return errorFRV
        }else{
            return createStackCell()
        }
    }
    
    func tableView(_ tableView: NSTableView, shouldSelectRow row: Int) -> Bool {
        return false
    }
    
}

class ExcelFRV: NSStackView {
    lazy var verticalStack: NSStackView = {
       let stack = NSStackView()
        stack.orientation = .vertical
        stack.distribution = .fill
        stack.spacing = 0
        return stack
    }()
    
    var model: FileResult
    
    init(model: FileResult, tag: Int) {
        self.model = model
        super.init(frame: .zero)
        self.viewTag = tag
        orientation = .horizontal
        distribution = .fill
        spacing = 0
        installCell()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func installCell() {
        Async(.global()) {[self] in
            var count: Int = 0
            for fileList in model.fileList {
                count += fileList.errorImportArray.count
            }
            Async(.main) {[self] in
                let frameworkNameCell = Excel(titleText: model.frameworkName)
                addArrangedSubview(frameworkNameCell)
                frameworkNameCell.snp.makeConstraints { make in
                    make.width.equalTo(130)
                }
            }
            for (idx, fileModel) in model.fileList.enumerated() {
                Async(.main) {[self] in
                    let fileV = ExcelFileV(model: fileModel, tag: viewTag * 10 + idx + 1)
                    verticalStack.addArrangedSubview(fileV)
                }
            }
            Async(.main) {[self] in
                addArrangedSubview(verticalStack)
            }
        }
    }
}

class ExcelFileV: NSStackView {
    
    lazy var verticalStack: NSStackView = {
       let stack = NSStackView()
        stack.orientation = .vertical
        stack.distribution = .fillEqually
        stack.spacing = 0
        return stack
    }()
    
    var model: FileNameModel
    
    init(model: FileNameModel, tag: Int) {
        self.model = model
        super.init(frame: .zero)
        self.viewTag = tag
        orientation = .horizontal
        distribution = .fill
        spacing = 0
        installCell()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func installCell() {
        Async(.global()) {[self] in
            Async(.main) {[self] in
                let fileNameCell = Excel(titleText: model.fileName)
                addArrangedSubview(fileNameCell)
                fileNameCell.snp.makeConstraints { make in
                    make.width.equalTo(200)
                }
            }
            for (idx, errorImportData) in model.errorImportArray.enumerated() {
                Async(.main) {[self] in
                    let errorLV = ExcelErrorLV(model: errorImportData, tag: viewTag * 10 + idx + 1)
                    verticalStack.addArrangedSubview(errorLV)
                }
            }
            Async(.main) {[self] in
                addArrangedSubview(verticalStack)
            }
        }
    }
    
}

class ExcelErrorLV: NSStackView {
    
    var model: ErrorInfo
    
    init(model: ErrorInfo, tag: Int) {
        self.model = model
        super.init(frame: .zero)
        self.viewTag = tag
        orientation = .horizontal
        distribution = .fill
        spacing = 0
        installCell()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func installCell() {
        let fileNameCell = Excel(titleText: model.fileName)
        let lineCell = Excel(titleText: "\(model.line)")
        let errorContentCell = Excel(titleText: model.importContent)
        let rightImportCell = Excel(titleText: model.rightImportContent)
        let replaceCell = ExcelButton()
        replaceCell.viewTag = viewTag
        addArrangedSubview(fileNameCell)
        addArrangedSubview(lineCell)
        addArrangedSubview(errorContentCell)
        addArrangedSubview(rightImportCell)
        addArrangedSubview(replaceCell)
        fileNameCell.snp.makeConstraints { make in
            make.size.equalTo(NSMakeSize(300, 40))
        }
        lineCell.snp.makeConstraints { make in
            make.size.equalTo(NSMakeSize(40, 40))
        }
        errorContentCell.snp.makeConstraints { make in
            make.size.equalTo(NSMakeSize(350, 40))
        }
        rightImportCell.snp.makeConstraints { make in
            make.size.equalTo(NSMakeSize(400, 40))
        }
        replaceCell.snp.makeConstraints { make in
            make.size.equalTo(NSMakeSize(100, 40))
        }
    }
}


class Excel: NSView {
    
    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)

        // Drawing code here.
    }
    
    lazy var titleLabel: NSTextField = {
        let tf = NSTextField()
        tf.isVerticalCenter = true
        tf.font = .systemFont(ofSize: 12)
        tf.isBordered = false
        tf.isEditable = false
        tf.textColor = .black
        tf.bezelStyle = .roundedBezel
        tf.stringValue = titleText
        tf.backgroundColor = .clear
        return tf
    }()
    
    lazy var copyButton: NSButton = {
        let button = NSButton()
//        button.setButtonType(.accelerator)
        button.title = ""
        button.target = self
        button.action = #selector(copyAction)
        button.isTransparent = true
        return button
    }()
    
    var titleText: String
    
    init(titleText: String) {
        self.titleText = titleText
        super.init(frame: .zero)
        wantsLayer = true
        layer?.borderColor = .black
        layer?.borderWidth = 1
        installView()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func installView() {
        Async(.main) {[self] in
            addSubview(titleLabel)
            titleLabel.snp.makeConstraints { make in
                make.center.equalToSuperview()
                make.left.equalTo(8)
                make.right.equalTo(-8)
            }
            
            addSubview(copyButton)
            copyButton.snp.makeConstraints { make in
                make.edges.equalTo(titleLabel)
            }
        }
    }
    
    override func mouseDown(with event: NSEvent) {
        copyAction()
    }
    
    @objc func copyAction() {
        let pasteboard = NSPasteboard.general
        pasteboard.clearContents()
        pasteboard.setString(titleText, forType: .string)
        if let controller = window?.contentViewController {
            let rect = convert(copyButton.frame, to: controller.view)
            controller.present(Toast(title: "复制成功"), asPopoverRelativeTo: NSRect(origin: rect.origin, size: frame.size), of: controller.view, preferredEdge: .minY, behavior: .transient)
        }
    }
}

class ExcelButton: NSView {
    
    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)

        // Drawing code here.
    }
    
    lazy var replaceButton: NSButton = {
        let button = NSButton()
        button.title = title
        button.target = self
        button.action = #selector(replaceButtonClick)
        return button
    }()
    
    var title: String
    
    init(title: String = "一键替换") {
        self.title = title
        super.init(frame: .zero)
        installView()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func installView() {
        Async(.main) {[self] in
            addSubview(replaceButton)
            replaceButton.snp.makeConstraints { make in
                make.center.equalToSuperview()
            }
        }
    }
    
    @objc func replaceButtonClick() {
        if viewTag == -2 {
            NotificationCenter.default.post(name: replaceFileNotification, object: nil, userInfo: ["tag" : "replaceAll"])
        }else{
            NotificationCenter.default.post(name: replaceFileNotification, object: nil, userInfo: ["tag" : viewTag])
        }
    }
}
